/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
* TreeActions.java
*
* Created on December 25, 2007, 5:56 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
 */
package gui.genomemap.tree;

import genomemap.maps.FullHybridizationMapComponent;
import genomemap.maps.XMap;

import gui.genomemap.outputModel.AnnealOModel;
import gui.genomemap.outputModel.ComGLHoodOModel;
import gui.genomemap.outputModel.ComJLHoodOModel;
import gui.genomemap.outputModel.ComPLHoodOModel;
import gui.genomemap.outputModel.OutputModel;
import gui.genomemap.outputModel.ProgCurveOModel;
import gui.genomemap.view.outputView.options.AnnealOOptions;
import gui.genomemap.view.outputView.options.ComGLHoodOOptions;
import gui.genomemap.view.outputView.options.ComJLHoodOOptions;
import gui.genomemap.view.outputView.options.ComPLHoodOOptions;
import gui.genomemap.view.outputView.options.OutputOptions;
import gui.genomemap.view.outputView.options.ProgCurveOOptions;

import javautil.graphics.GraphicsUtil;
import javautil.io.IOUtil;
import javautil.swing.SwingUtil;

import org.jfree.chart.ChartPanel;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JFileChooser;
import javax.swing.KeyStroke;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.TreePath;

/**
 *
 * @author stewari1
 */
class TreeActions {

    /** Field description */
    public static final String KEY_DELETE_MODEL = "deleteModel";

    /** Field description */
    public static final String KEY_EDIT_MODEL = "editModel";

    /** Field description */
    public static final String KEY_CREATE_MODEL = "createModel";

    /** Field description */
    public static final String KEY_OUTPUT_OPTIONS = "outputOptions";

    /** Field description */
    public static final String KEY_SAVE_AS = "saveAs";

    /** Field description */
    private final ActionMap treeActionMap = new ActionMap();

    /** Field description */
    private final InputMap treeInputMap = new InputMap();

    /**
     * Creates a new instance of TreeActions
     * @param tree
     */
    public TreeActions(final ViewTree tree) {


        // Action: deleteModel
        ImageIcon deleteModelIcon = new ImageIcon("resources/icons/delete_16.png");

        getTreeInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), KEY_DELETE_MODEL);

        Action deleteModelAction = new AbstractAction("Delete", deleteModelIcon) {

            public void actionPerformed(ActionEvent e) {

                if (tree != null) {

                    TreePath[] selectedPaths = tree.getSelectionPaths();

                    if (selectedPaths != null) {

                        tree.getView().getManager().removeOutputModels(
                            tree.getOutputModels(selectedPaths));
                    }
                }
            }
        };

        getTreeActionMap().put(KEY_DELETE_MODEL, deleteModelAction);


        // Action: editModel
        ImageIcon editModelIcon = new ImageIcon("resources/icons/edit_16.png");

        getTreeInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), KEY_EDIT_MODEL);

        Action editModelAction = new AbstractAction("Edit", editModelIcon) {

            public void actionPerformed(ActionEvent e) {

                if (tree != null) {

                    TreePath[] selectedPaths = tree.getSelectionPaths();

                    if ((selectedPaths != null) && (selectedPaths.length == 1)) {

                        ModelTreeNode modelNode =
                            (ModelTreeNode) selectedPaths[0].getLastPathComponent();

                        if (modelNode != null) {

                            modelNode.getOutputModel().setEditable(true);
                            tree.getView().displayOutputModel(modelNode);
                        }
                    }
                }
            }
        };

        getTreeActionMap().put(KEY_EDIT_MODEL, editModelAction);


        // Action: createModel
        ImageIcon createModelIcon = new ImageIcon("resources/icons/edit_16.png");

        getTreeInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0), KEY_CREATE_MODEL);

        Action createModelAction = new AbstractAction("Create Model", createModelIcon) {

            public void actionPerformed(ActionEvent e) {

                if (tree != null) {

                    TreePath selectedPath = tree.getSelectionPath();

                    tree.getView().displayOutputModel(null);
                }
            }
        };

        getTreeActionMap().put(KEY_CREATE_MODEL, createModelAction);


        // Action: OutputOptions
        Action outputOptionsAction = new AbstractAction("Output Options") {

            public void actionPerformed(ActionEvent e) {

                if (tree != null) {

                    TreePath[] selectedPaths = tree.getSelectionPaths();

                    if ((selectedPaths != null) && (selectedPaths.length == 1)) {

                        ModelTreeNode modelNode =
                            (ModelTreeNode) selectedPaths[0].getLastPathComponent();

                        if (modelNode != null) {

                            OutputOptions optionsDialog = null;
                            OutputModel outputModel     = modelNode.getOutputModel();

                            if (outputModel instanceof ComGLHoodOModel) {

                                optionsDialog =
                                    (ComGLHoodOOptions) tree.getView().getOutputView()
                                        .getOptionsDialog();
                            }

                            if (outputModel instanceof ComPLHoodOModel) {

                                optionsDialog =
                                    (ComPLHoodOOptions) tree.getView().getOutputView()
                                        .getOptionsDialog();
                            }

                            if (outputModel instanceof ComJLHoodOModel) {

                                optionsDialog =
                                    (ComJLHoodOOptions) tree.getView().getOutputView()
                                        .getOptionsDialog();
                            }

                            if (outputModel instanceof AnnealOModel) {

                                optionsDialog =
                                    (AnnealOOptions) tree.getView().getOutputView()
                                        .getOptionsDialog();
                            }

                            if (outputModel instanceof ProgCurveOModel) {

                                optionsDialog =
                                    (ProgCurveOOptions) tree.getView().getOutputView()
                                        .getOptionsDialog();
                            }

                            optionsDialog.setModelTreeNode(modelNode);
                            optionsDialog.setLocationRelativeTo(null);
                            optionsDialog.setVisible(true);
                        }
                    }
                }
            }
        };

        getTreeActionMap().put(KEY_OUTPUT_OPTIONS, outputOptionsAction);


        // Action: Save As : different depending on the node type
        Action saveAsAction = new AbstractAction("Save As") {

            @Override
            public void actionPerformed(ActionEvent e) {

                if (tree != null) {

                    TreePath[] selectedPaths = tree.getSelectionPaths();

                    if ((selectedPaths != null) && (selectedPaths.length == 1)) {

                        ViewTreeNode viewTreeNode =
                            (ViewTreeNode) selectedPaths[0].getLastPathComponent();

                        if (viewTreeNode != null) {

                            if (viewTreeNode instanceof ModelFigTreeNode) {

                                ModelFigTreeNode figTreeNode = (ModelFigTreeNode) viewTreeNode;
                                File saveAsFile              = null;
                                FileFilter jpegFilter = new FileNameExtensionFilter("JPEG", "jpeg");
                                FileFilter pngFilter = new FileNameExtensionFilter("PNG", "png");
                                FileFilter selectedFilter    = null;
                                JFileChooser chooser         = new JFileChooser();

                                chooser.addChoosableFileFilter(jpegFilter);
                                chooser.addChoosableFileFilter(pngFilter);

                                int returnVal = chooser.showSaveDialog(null);

                                if (returnVal != JFileChooser.APPROVE_OPTION) {
                                    return;
                                }

                                saveAsFile     = chooser.getSelectedFile();
                                selectedFilter = chooser.getFileFilter();

                                if ((saveAsFile != null) && (selectedFilter != null)) {


                                    // Note: reference matching is deliberate
                                    Component comp = figTreeNode.getFigureComp();
                                    String format  = GraphicsUtil.IMAGE_FORMAT_JPEG;

                                    if (selectedFilter == pngFilter) {
                                        format = GraphicsUtil.IMAGE_FORMAT_PNG;
                                    }

                                    if (comp instanceof XMap) {

                                        XMap xMap = (XMap) comp;

                                        GraphicsUtil.saveImage(saveAsFile, format, xMap,
                                                               xMap.getWidth(), xMap.getHeight());
                                    }

                                    if (comp instanceof FullHybridizationMapComponent) {

                                        FullHybridizationMapComponent fullMap =
                                            (FullHybridizationMapComponent) comp;

                                        GraphicsUtil.saveImage(saveAsFile, format, fullMap,
                                                               fullMap.getWidth(),
                                                               fullMap.getHeight());
                                    }

                                    if (comp instanceof ChartPanel) {

                                        ChartPanel chartPanel = (ChartPanel) comp;

                                        GraphicsUtil.saveImage(saveAsFile, format, 200, 300,
                                                               chartPanel);
                                    }
                                }
                            }

                            if (viewTreeNode instanceof ModelStatTreeNode) {

                                ModelStatTreeNode statTreeNode = (ModelStatTreeNode) viewTreeNode;
                                File saveAsFile = SwingUtil.getFileFromSaveAs(null,
                                                      new FileNameExtensionFilter("HTML Files",
                                                          "html", "htm"));

                                if (saveAsFile != null) {

                                    try {
                                        IOUtil.writeToFile(saveAsFile, statTreeNode.getModelStat());
                                    } catch (IOException ex) {
                                        ex.printStackTrace();
                                    }
                                }
                            }

                            if (viewTreeNode instanceof ModelLogTreeNode) {

                                ModelLogTreeNode logTreeNode = (ModelLogTreeNode) viewTreeNode;
                                File saveAsFile = SwingUtil.getFileFromSaveAs(null,
                                                      new FileNameExtensionFilter("TXT Files",
                                                          "txt", "dat"));

                                if (saveAsFile != null) {

                                    try {
                                        IOUtil.writeToFile(saveAsFile, logTreeNode.getLog());
                                    } catch (IOException ex) {
                                        ex.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        };

        getTreeActionMap().put(KEY_SAVE_AS, saveAsAction);
    }

    public ActionMap getTreeActionMap() {
        return treeActionMap;
    }

    public InputMap getTreeInputMap() {
        return treeInputMap;
    }
}
